<template>
  <div class="role-wrap">
    <!-- 添加按钮 -->
    <div class="add-btn">
      <el-button v-permission="'add'" type="primary" @click="addRole">添加角色</el-button>
    </div>
    <!-- table表格 -->
    <el-table
      :data="roleList"
      style="width: 100%"
    >
      <el-table-column
        label="角色"
        width="180"
      >
        <template v-slot="{row}">
          <div v-if="!row.isEdit">{{ row.name }}</div>
          <el-input v-else v-model="editRow.name" />
        </template>
      </el-table-column>
      <el-table-column
        label="启用"
        width="180"
      >
        <!-- <div slot-scope="scope" @click="fn(scope)">
          {{ scope.row.state === 1 ? '已启用' : '未启用' }}
        </div> -->
        <!-- <template v-slot="scope"> -->
        <template #default="scope">
          <el-switch v-if="scope.row.isEdit" v-model="editRow.state" :active-value="1" :inactive-value="0" />
          <div v-else>{{ scope.row.state === 1 ? '已启用' : '未启用' }}</div>
        </template>
      </el-table-column>
      <el-table-column
        label="描述"
      >
        <template v-slot="{row}">
          <el-input v-if="row.isEdit" v-model="editRow.description" type="textarea" />
          <div v-else>{{ row.description }}</div>
        </template>
      </el-table-column>
      <el-table-column
        label="操作"
        width="200"
      >
        <template v-slot="{ row }">
          <div v-if="row.isEdit">
            <el-button type="primary" size="mini" @click="updateRole">确定</el-button>
            <el-button size="mini" @click="row.isEdit = false">取消</el-button>
          </div>
          <div v-else>
            <el-button type="text" @click="assignPermission(row.id)">分配权限</el-button>
            <el-button type="text" style="margin-right: 5px" @click="editLine(row)">编辑</el-button>
            <!-- <el-button type="text" @click="deleteRole(row.id)">删除</el-button> -->
            <!-- 气泡弹出框组件 elmenet-ui官网 有变动，我们这个项目是 2.13.2的elemnt-ui， 看文档要注意版本 -->
            <el-popconfirm
              title="是否删除改角色"
              @onConfirm="deleteRole(row.id)"
              @onCancel="delCancel"
            >
              <el-button slot="reference" type="text">删除</el-button>
            </el-popconfirm>
          </div>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页插件 -->
    <div>
      <!-- 分页插件有很多默认值，当前页码值默认第一页，每页显示条数默认10条 -->
      <el-pagination
        :current-page="page"
        :page-sizes="[3, 5, 10, 20]"
        :page-size="pagesize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>

    <!-- 弹出框组件 -->
    <!-- 在父组件里面要打开子组件封装的弹出框，我们学习两个方法 -->
    <!-- 第一个方法： 在父组件里面定义 打开的变量， 点击以后修改变量的值，在父向子传值 -->
    <!-- 第二个方法： 变量在子组件自己里面定义，父组件通过$refs去访问子组件的方法 -->
    <!-- ref给普通元素 如div添加，就是当前dom元素，如果给自定义组件添加，就是获取当前组件实例对象 -->
    <addDialog ref="addRef" @ADD_ROLE_SUCCESS="addSuccess" />

    <!-- 给角色分配权限的弹出框 -->
    <assignPermission v-if="value" :id="id" v-model="value" />
  </div>
</template>

<script>
import { getRoleListRequest, updateRoleRequest, deleteRoleRequest } from '@/api/role'
import addDialog from './components/addDialog.vue'
import assignPermission from './components/AssignPermission.vue'
import lodash from 'lodash'

export default {
  components: { addDialog, assignPermission },
  data() {
    return {
      roleList: [],
      total: 0,
      page: 1,
      pagesize: 3,
      editRow: {},
      id: 0,
      value: false
    }
  },
  computed: {
    // 最大页码值
    maxPage() {
      return Math.ceil(this.total / this.pagesize)
    },
    // 每页数据是否刚好填满
    isFullPage() {
      return this.total % this.pagesize === 0
    }
  },
  created() {
    this.getRoleList()
  },
  methods: {
    async getRoleList() {
      const res = await getRoleListRequest({ page: this.page, pagesize: this.pagesize })
      // 下面这句话，就是将data上面的数据，roleList数组里面的每个对象的每个属性，都转换为get set的函数形式，这个vue的源码，也是vue为什么有响应式的原因
      this.roleList = res.data.rows
      // 给数组的，每一个对象添加一个属性 isEdit， 表示当前行是否是编辑状态
      this.roleList.forEach(item => {
        // 下面这样直接修改对象，添加新属性，不会触发vue的响应式（js的数据发生了改变，但是页面view没有发生变化）
        // item.isEdit = false
        // $set 数据在初始化之后，想添加新的属性，并且要想有响应式，就通过$set去添加
        // 不能触发响应式的操作： 对象属性的添加和删除。  数组通过索引号 和 修改长度
        // 怎么样处理： 对象就用$set.  数组就用7个数组编译方法 push splice这些
        this.$set(item, 'isEdit', false)
      })
      this.total = res.data.total
    },
    handleSizeChange(value) {
      this.pagesize = value
      this.getRoleList()
    },
    handleCurrentChange(value) {
      this.page = value
      this.getRoleList()
    },
    addRole() {
      console.log(this.$refs.addRef)
      this.$refs.addRef.openDialog()
    },
    addSuccess() {
      // 需求，我们添加完数据以后，用户想直接跳转到添加数据的那个分页，现在就是页码值我们需要自己修改以下
      // 需要几个变量  总数据条数 this.total = 50   每页显示的数据条数  this.pagesize = 10
      // 判断的时候，需要两个值  最大页码值： Math.ceil(this.total / this.pagesize)
      // 每页数据是否刚好填满  this.total % this.pagesize === 0
      if (this.isFullPage) {
        this.page = this.maxPage + 1
      } else {
        this.page = this.maxPage
      }
      // 还可以完善最后一页如果填满，那么分页插件的分页不会跳到最后一页
      // 这个需要在请求结束以后，有了新数据，再去跳转，因为只有请求回来以后
      // 页面有了3页，才能跳过去，如果先把页码值改为了3，但是页码值一共就只有2，就不行
      // 需要改造getRoleList函数，有需要的同学可以去做一下
      this.getRoleList()
    },
    // 编辑按钮
    editLine(item) {
      item.isEdit = true
      // 在编辑的时候，我们应该创建一个新对象，也就是一个新地址
      // 这样的话，改变新数据，就不影响原始数组里面的对象数据。起到了数据隔离的作用
      this.editRow = lodash.cloneDeep(item)
    },
    async updateRole() {
      delete this.editRow.isEdit
      await updateRoleRequest(this.editRow)
      // 更新完毕以后，刷新页面，将数据重置
      this.getRoleList()
      this.editRow = this.$options.data().editRow
    },
    // 删除
    async deleteRole(id) {
      await deleteRoleRequest(id)
      this.getRoleList()
    },
    delCancel() {},
    assignPermission(id) {
      this.id = id
      this.value = true
    }
  }
}
</script>
